<?php

namespace App\Jobs;

use App\Models\Room;
use App\Repositories\RoomRepository;
use App\Services\LogService;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class ProcessExpiredRooms implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    /**
     * 任务超时时间（秒）
     */
    public int $timeout = 300;

    /**
     * 任务重试次数
     */
    public int $tries = 3;

    /**
     * Create a new job instance.
     */
    public function __construct()
    {
        //
    }

    /**
     * Execute the job.
     */
    public function handle(RoomRepository $roomRepository, LogService $logService): void
    {
        try {
            Log::info('开始处理过期房间任务');

            // 获取所有过期的房间
            $expiredRooms = $roomRepository->getExpiredRooms();
            
            if ($expiredRooms->isEmpty()) {
                Log::info('没有发现过期房间');
                return;
            }

            Log::info("发现 {$expiredRooms->count()} 个过期房间");

            $processedCount = 0;
            $errorCount = 0;

            foreach ($expiredRooms as $room) {
                try {
                    DB::beginTransaction();

                    // 标记房间为过期
                    $roomRepository->markAsExpired($room->id);

                    // 记录房间过期活动
                    $logService->logRoomActivity('房间自动过期', $room, [
                        'expired_at' => now(),
                        'room_type' => $room->type,
                        'expires_at' => $room->expires_at,
                    ]);

                    // 可以在这里添加其他过期处理逻辑
                    // 比如：通知房间成员、清理相关数据等
                    $this->handleRoomExpiration($room);

                    DB::commit();
                    $processedCount++;

                    Log::info("房间 {$room->room_id} 已标记为过期");

                } catch (\Exception $e) {
                    DB::rollBack();
                    $errorCount++;
                    
                    Log::error("处理房间 {$room->room_id} 过期时出错", [
                        'error' => $e->getMessage(),
                        'room_id' => $room->id,
                    ]);
                }
            }

            Log::info("过期房间处理完成", [
                'processed' => $processedCount,
                'errors' => $errorCount,
                'total' => $expiredRooms->count(),
            ]);

        } catch (\Exception $e) {
            Log::error('处理过期房间任务失败', [
                'error' => $e->getMessage(),
                'trace' => $e->getTraceAsString(),
            ]);
            
            throw $e;
        }
    }

    /**
     * 处理房间过期的具体逻辑
     */
    private function handleRoomExpiration(Room $room): void
    {
        // 可以在这里添加更多过期处理逻辑
        // 比如：
        // 1. 通知所有房间成员房间已过期
        // 2. 清理房间相关的临时数据
        // 3. 生成房间统计报告
        // 4. 发送过期通知给创建者
        
        Log::info("执行房间 {$room->room_id} 的过期后处理逻辑");
    }

    /**
     * 任务失败时的处理
     */
    public function failed(\Throwable $exception): void
    {
        Log::error('处理过期房间任务失败', [
            'error' => $exception->getMessage(),
            'trace' => $exception->getTraceAsString(),
        ]);
    }
}
